package cc.autoapi.pucong.auto.flow.core.flow.execNode.task.system;


import cc.autoapi.pucong.auto.flow.core.flow.execNode.entity.node.*;
import cc.autoapi.pucong.auto.flow.core.flow.execNode.exception.AutoDesignException;
import cc.autoapi.pucong.auto.flow.core.flow.execNode.task.AbstractTask;
import cn.hutool.script.ScriptUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class JsScriptTask extends AbstractTask {

    private List<NodeParamIn> paramsIns;
    private List<NodeParamOut> paramsOuts;

    public JsScriptTask() {
        paramsIns = new ArrayList<>();

        paramsOuts = new ArrayList<>();
    }

    @Override
    public void run() {
        String nodeScript = getExecNode().getNodeScript();
        if (StringUtils.isBlank(nodeScript)) {
            throw new AutoDesignException("脚本内容不能为空！,节点名称：" + getExecNode().getNodeName());
        }
        // 执行脚本
        ExecNode execNode = getExecNode();
        List<ExecParamIn> paramInList = execNode.getParamInList();
        JSONObject jsonObjectParams = new JSONObject();
        for (ExecParamIn paramIn : paramInList) {
            if (paramIn.getParamCode().equals("jsScript")) {
                continue;
            }
            String paramCode = paramIn.getParamCode();
            Object dateValue1 = paramIn.getDateValue();
            jsonObjectParams.put(paramCode, dateValue1);
        }
        // 执行
        Object run = null;
        Object json = null;
        synchronized (JsScriptTask.class) {
            run = ScriptUtil.invoke(nodeScript, "run", jsonObjectParams);
        }
        if (run instanceof ScriptObjectMirror) {
            ScriptObjectMirror res = (ScriptObjectMirror) run;
            json = toObject(res);
        } else {
            json = run;
        }
        if (json instanceof JSONObject) {
            JSONObject jsonObject = (JSONObject) json;
            List<ExecParamOut> paramOutList = execNode.getParamOutList();
            for (ExecParamOut execParamOut : paramOutList) {
                String paramCode = execParamOut.getParamCode();
                setParamOutValue(paramCode, jsonObject.get(paramCode));
            }
        } else {
            throw new AutoDesignException("脚本返回值只能是对象！,节点名称：" + getExecNode().getNodeName());
        }
    }

    public static Object toObject(ScriptObjectMirror mirror) {
        if (mirror.isEmpty()) {
            return null;
        }
        if (mirror.isArray()) {
            JSONArray list = new JSONArray();
            for (Map.Entry<String, Object> entry : mirror.entrySet()) {
                Object result = entry.getValue();
                if (result instanceof ScriptObjectMirror) {
                    list.add(toObject((ScriptObjectMirror) result));
                } else {
                    list.add(result);
                }
            }
            return list;
        }

        JSONObject map = new JSONObject();
        for (Map.Entry<String, Object> entry : mirror.entrySet()) {
            Object result = entry.getValue();
            if (result instanceof ScriptObjectMirror) {
                map.put(entry.getKey(), toObject((ScriptObjectMirror) result));
            } else {
                map.put(entry.getKey(), result);
            }
        }
        return map;
    }

    @Override
    public String getTaskName() {
        return "js脚本节点";
    }

    @Override
    public String getTaskDesc() {
        return "   本组件可以把脚本内容设置到“script”属性。\n" +
                "                本组件只能用来做数据处理，无法实现复杂的业务功能。\n" +
                "                脚本内容需要存在function run(context)方法，JavaScrip 是ES5版本，且会使用es5语法执行脚本，脚本内容尽量不要超过20行。\n" +
                "                脚本示例：\n" +
                "                function run(context){\n" +
                "                    return {\n" +
                "                        context.a\n" +
                "                    }\n" +
                "                }";
    }

    @Override
    public Boolean getTaskParamInAuto() {
        return true;
    }

    @Override
    public String getTaskSvgIcon() {
        return "<svg t=\"1728283644819\" class=\"icon\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"6526\" width=\"32\" height=\"32\"><path d=\"M923.136 969.557333H193.024v-909.653333h521.386667l208.725333 207.701333z\" fill=\"#7CCDFF\" p-id=\"6527\"></path><path d=\"M912.896 253.952l2.56 671.914667c0 15.530667-12.458667 27.989333-27.989333 27.989333H237.909333c-15.530667 0-27.989333-12.458667-27.989333-27.989333V96.938667c0-15.530667 12.458667-27.989333 27.989333-27.989334l493.397334-1.024-38.912-39.936H239.274667c-36.352 0-65.706667 29.354667-65.706667 65.706667v835.584c0 36.352 29.354667 65.706667 65.706667 65.706667h646.826666c36.352 0 65.706667-29.354667 65.706667-65.706667V293.888l-38.912-39.936z\" fill=\"#4191FB\" p-id=\"6528\"></path><path d=\"M692.394667 222.72c0 39.424 31.914667 71.338667 71.338666 71.338667h188.245334L692.394667 27.989333v194.730667z\" fill=\"#C7E2FF\" p-id=\"6529\"></path><path d=\"M557.568 482.304H158.72c-50.346667 0-91.136-40.789333-91.136-91.136v-60.245333c0-50.346667 40.789333-91.136 91.136-91.136h398.848c50.346667 0 91.136 40.789333 91.136 91.136v60.245333c0 50.346667-40.789333 91.136-91.136 91.136z\" fill=\"#4191FB\" p-id=\"6530\"></path><path d=\"M283.989333 287.573333h48.298667v84.650667c0 17.749333-1.536 31.232-4.778667 40.618667-3.072 9.216-9.557333 17.066667-18.944 23.552-9.557333 6.485333-21.674667 9.728-36.522666 9.728-15.701333 0-27.989333-2.048-36.522667-6.314667-8.704-4.266667-15.36-10.410667-19.968-18.602667-4.778667-8.192-7.509333-18.261333-8.362667-30.378666l46.08-6.314667c0 6.826667 0.682667 11.946667 1.877334 15.36 1.194667 3.413333 3.072 5.973333 5.802666 8.021333 1.877333 1.365333 4.437333 2.048 7.850667 2.048 5.461333 0 9.386667-2.048 11.776-5.973333 2.56-3.925333 3.754667-10.752 3.754667-20.138667v-96.256h-0.341334zM355.84 391.850667l45.738667-2.901334c1.024 7.509333 3.072 13.141333 5.973333 17.066667 4.949333 6.314667 12.117333 9.386667 21.162667 9.386667 6.826667 0 12.117333-1.536 15.872-4.778667 3.754667-3.242667 5.632-6.997333 5.632-11.264 0-4.096-1.706667-7.68-5.290667-10.752-3.584-3.242667-11.776-6.144-24.576-9.045333-21.162667-4.778667-36.181333-11.093333-45.226667-18.944s-13.653333-17.92-13.653333-30.037334c0-8.021333 2.389333-15.530667 6.997333-22.698666 4.608-7.168 11.605333-12.629333 20.992-16.725334 9.386667-4.096 22.016-6.144 38.229334-6.144 19.968 0 35.157333 3.754667 45.568 11.093334s16.725333 19.114667 18.602666 35.328l-45.397333 2.730666c-1.194667-6.997333-3.754667-12.117333-7.68-15.36-3.925333-3.242667-9.216-4.778667-16.042667-4.778666-5.632 0-9.728 1.194667-12.629333 3.584-2.901333 2.389333-4.266667 5.290667-4.266667 8.704 0 2.56 1.194667 4.778667 3.584 6.656 2.218667 2.048 7.68 3.925333 16.213334 5.802666 20.992 4.608 36.181333 9.045333 45.226666 13.824 9.045333 4.608 15.701333 10.410667 19.797334 17.237334s6.144 14.506667 6.144 23.04c0 10.069333-2.730667 19.114667-8.362667 27.648-5.461333 8.362667-13.312 14.848-23.210667 19.114666-9.898667 4.437333-22.357333 6.485333-37.546666 6.485334-26.453333 0-44.885333-5.12-54.954667-15.36-9.728-10.24-15.530667-23.210667-16.896-38.912z\" fill=\"#FFFFFF\" p-id=\"6531\"></path><path d=\"M872.618667 747.349333c0 28.672-0.170667 57.514667 0 86.186667 0.170667 20.992-8.533333 36.693333-26.453334 47.274667-44.714667 26.794667-89.6 53.077333-133.973333 80.384-21.845333 13.482667-42.325333 12.629333-63.317333-0.682667-6.826667-4.437333-14.336-7.850667-20.992-12.458667-7.168-4.949333-10.581333-11.776-5.802667-20.138666 5.12-8.704 12.8-11.264 21.845333-6.656 9.045333 4.608 17.749333 9.728 26.453334 14.848 7.850667 4.608 15.189333 4.608 23.04-0.170667 45.568-27.477333 91.306667-54.784 136.874666-82.090667 7.509333-4.437333 10.752-10.752 10.752-19.285333 0-58.368-0.170667-116.565333 0-174.933333 0-9.216-4.096-15.530667-11.776-19.968-47.445333-27.477333-94.72-54.954667-142.165333-82.602667-7.168-4.096-13.824-4.266667-20.992-0.170667-48.128 27.818667-96.085333 55.808-144.213333 83.456-6.826667 3.925333-9.386667 9.557333-9.386667 17.408 0.170667 59.392 0.170667 118.954667 0 178.346667 0 7.850667 2.901333 13.312 9.728 17.066667 17.408 9.557333 34.304 19.797333 52.053333 28.842666 21.504 10.922667 38.058667 0.341333 38.058667-24.064 0.170667-58.368 0-116.565333 0.170667-174.933333 0-5.12-2.56-12.117333 4.266666-14.336 7.338667-2.56 15.36-2.389333 22.869334 0.170667 3.413333 1.194667 3.413333 4.949333 3.413333 8.021333-0.512 62.122667 2.730667 124.416-1.536 186.368-3.072 44.373333-44.373333 65.536-84.821333 44.885333-17.237333-8.874667-33.962667-18.773333-50.858667-28.501333-17.92-10.24-25.770667-26.282667-25.941333-46.421333-0.170667-57.856-0.170667-115.882667 0-173.738667 0.170667-21.504 9.557333-37.376 28.842666-48.298667 45.909333-25.941333 91.477333-52.736 137.045334-79.701333 19.968-11.776 39.082667-12.458667 59.221333-0.341333 46.08 27.306667 92.501333 54.101333 139.093333 80.896 19.456 11.264 28.330667 27.648 27.989334 49.834666 0.170667 28.672 0.512 57.002667 0.512 85.504z\" fill=\"#4191FB\" p-id=\"6532\"></path><path d=\"M736.085333 840.533333c-8.362667 0.170667-19.456-1.706667-30.208-4.949333-21.504-6.314667-37.034667-25.941333-38.570666-47.786667-0.341333-5.290667 1.365333-7.68 6.656-8.533333 15.530667-2.389333 19.797333-0.170667 25.770666 14.848 3.754667 9.386667 10.581333 14.848 20.138667 17.578667 13.653333 3.754667 26.965333 2.218667 40.277333-1.194667 8.192-2.048 15.018667-6.997333 15.872-16.554667 0.853333-9.728-4.096-16.896-12.629333-20.309333-13.653333-5.461333-27.818667-9.898667-41.642667-14.677333-7.338667-2.56-14.677333-5.12-21.845333-7.850667-16.725333-6.314667-27.477333-17.92-28.16-36.352-0.853333-17.408 7.509333-31.402667 22.528-39.424 28.330667-15.018667 57.685333-14.506667 85.845333 0.853333 13.482667 7.338667 18.602667 21.333333 21.504 35.84 0.512 2.389333 0.512 4.608-1.877333 6.314667-6.144 4.437333-25.088 0.170667-28.672-6.656-10.24-19.968-42.837333-27.989333-61.610667-15.189333-10.581333 7.168-10.24 22.016 1.194667 29.184 6.144 3.754667 13.312 6.144 20.309333 8.704 16.042667 5.973333 32.426667 10.922667 48.128 17.578666 17.92 7.68 28.842667 24.234667 27.648 40.96-1.365333 19.626667-11.776 33.28-29.866666 40.96-12.117333 4.778667-24.746667 6.485333-40.789334 6.656z\" fill=\"#4191FB\" p-id=\"6533\"></path></svg>";
    }

    @Override
    public List<NodeParamIn> getPropertyParamsIns() {
        return paramsIns;
    }

    @Override
    public List<NodeParamOut> getPropertyParamsOuts() {
        return paramsOuts;
    }
}
